#ifndef __TOYM__NET__CONNECTOR_H__
#define __TOYM__NET__CONNECTOR_H__

#include "net/Callables.h"
#include "net/InetAddress.h"
#include "net/Channel.h"
#include "Base/noncopyable.h"

namespace toym
{
namespace net
{

class EventLoop;
class Socket;

class Connector: noncopyable {
public:
    Connector(EventLoop* loop, const InetAddress& addr);
    ~Connector();
    void start();
    void restart();
    void stop();
    const InetAddress& getServerAddr() const {
        return m_addr;
    }
    void setConnectedCallback(const ConnectedCallback_t& cb) {
        this->m_connectedCb = cb;
    }
    void setConnectedCallback(ConnectedCallback_t&& cb) {
        this->m_connectedCb = std::move(cb);
    }

private:

    enum class State { eDisconnected, eConnecting, eConnected };

    void setState(State s) {
        this->m_state = s;
    }

    void startInLoop();
    void stopInLoop();
    void connect();
    void connecting(int sockfd);
    void handleWrite();
    void handleError();
    void retry(int sockfd);
    int removeAndResetChannel();
    void resetChannel();

    EventLoop* m_loop;
    InetAddress m_addr;
    std::unique_ptr<Channel> m_channel;
    ConnectedCallback_t m_connectedCb;
    State m_state;
    bool m_connected;
    int m_retryDelayMs;

    static const int s_maxRetryDelayMs;
    static const int s_initRetryDelayMs;
};

} // namespace net

} // namespace toym



#endif